package com.wyzt.page.service;

import com.wyzt.common.enums.ExceptionEnum;
import com.wyzt.common.exception.WyztException;
import com.wyzt.common.utils.ThreadUtils;
import com.wyzt.item.pojo.*;
import com.wyzt.page.client.BrandClient;
import com.wyzt.page.client.CategoryClient;
import com.wyzt.page.client.GoodsClient;
import com.wyzt.page.client.SpecificationClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.FileCopyUtils;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.File;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class PageService {

    @Autowired
    private GoodsClient goodsClient;
    @Autowired
    private BrandClient brandClient;
    @Autowired
    private CategoryClient categoryClient;
    @Autowired
    private SpecificationClient specificationClient;

    @Autowired
    private TemplateEngine templateEngine;

    // TODO: 2018/12/5 生成的html文件上传至 /path/to/nginx/html/item/xxx.html
    String destPath = "E:\\test"; //nginx的目录下文件夹

    public Map<String, Object> getGoodsDetails(Long spuId) {
        //spu
        Spu spu = goodsClient.querySpuById(spuId);
        if (spu == null) {
            throw new WyztException(ExceptionEnum.SPU_NOT_FOUND);
        }
        //spuDetail
        SpuDetail spuDetail = goodsClient.querySpuDetailById(spuId);
        if (spuDetail == null) {
            throw new WyztException(ExceptionEnum.SPU_NOT_FOUND);
        }
        //sku和stock
        List<Sku> skus = goodsClient.querySkuListById(spuId);
        if (CollectionUtils.isEmpty(skus)) {
            throw new WyztException(ExceptionEnum.GOODS_SKU_NOT_FOUND);
        }
        //查询分类
        List<Brand> brands = brandClient.queryBrandByIds(Arrays.asList(spu.getBrandId()));
        if (CollectionUtils.isEmpty(brands)) {
            throw new WyztException(ExceptionEnum.BRAND_NOT_FOUND);
        }
        //三级分类
        List<Category> categories = categoryClient.queryParentByCid3(spuId);
        if (CollectionUtils.isEmpty(categories)) {
            throw new WyztException(ExceptionEnum.CATEGORY_NOT_FOUND);
        }

        HashMap<String, Object> map = new HashMap<>();
        map.put("spu", spu);
        map.put("spuDetail", spuDetail);
        map.put("skus", skus);
        map.put("categories", categories);
        map.put("brand", brands.get(0));

        return map;
    }

    /**
     * 生成静态页面
     *
     * @param spuId
     */
    public void createHtml(Long spuId) {
        //上下文
        Context context = new Context();
        context.setVariables(getGoodsDetails(spuId));
        //输出流

        //准备一个输出流对象，关联一个临时文件
        File temp = new File(spuId + ".html");
        //创建一个目标文件
        File dest = this.createPath(spuId);
        //创建一个临时文件的文件夹
        File bak = new File(spuId + "_bak.html");

        try (PrintWriter writer = new PrintWriter(temp, "utf-8")) {
            templateEngine.process("item", context, writer);
            //如果旧文件存在、则先把目标文件转移到临时文件、然后覆盖
            if (dest.exists()) {
                dest.renameTo(bak);
            }
            //用新文件将旧文件覆盖
            FileCopyUtils.copy(temp, dest);
            //删除成功将备份文件删除
            bak.delete();
        } catch (Exception e) {
            //发生异常、还原旧文件
            bak.renameTo(dest);
            throw new RuntimeException(e);
        } finally {
            if (temp.exists()) {
                temp.delete();
            }
        }

    }

    /**
     * 根据id创建一个文件
     *
     * @param id
     * @return
     */
    public File createPath(Long id) {
        if (id == null) {
            return null;
        }
        //创建路径
        File dest = new File(this.destPath);
        if (!dest.exists()) {
            dest.mkdirs();
        }
        return new File(dest, id + ".html");
    }

    /**
     * 异步创建页面
     *
     * @param spuId
     */
    public void asyncCreateHtml(Long spuId) {
        ThreadUtils.execute(() -> createHtml(spuId));
    }

    /**
     * 删除静态页面
     *
     * @param spuId
     */
    public void deleteHtml(Long spuId) {
        File file = new File(destPath + spuId + ".html");
        file.deleteOnExit();
    }
}
